package org.itboys.fuzion.kuaiqian;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.itboys.weixin.tools.HttpHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Maps;

public class KQService {
	public static void main(String[] args) {
		KQPayInfo info=new KQPayInfo(1l, BigDecimal.ONE, 1l);
		post(info);
	}
	private static Logger logger = LoggerFactory.getLogger(KQService.class);
	private static Pkipair pki = new Pkipair();

	public static void post(KQPayInfo info) {
		System.out.println(getString(info));
		System.out.println(pki.signMsg(getString(info)));
		info.setSignMsg(pki.signMsg(getString(info)));
		String result = HttpHelper.doPostWithUtf8(KQConfig.actionUrl, getMap(info));
		System.out.println("result="+result);
	}

	public static String postAndResult(KQPayInfo info) {
		System.out.println(getString(info));
		System.out.println(pki.signMsg(getString(info)));
		info.setSignMsg(pki.signMsg(getString(info)));
		return KQConfig.actionUrl + "?" + getString2(info);
	}

	/**
	 * 块钱回调校验
	 * @param request
	 * @return
     */
	public static KQResult verify(HttpServletRequest request) {
		KQResultInfo info=new KQResultInfo(request);
		logger.info("****************************KQService.verify KQResultInfo="+ JSON.toJSONString(info));
		KQResult result=new KQResult();
		if(StringUtils.equals(info.getPayResult(), "10")){
			result.setTradeStatus(KQResult.success);
			result.setOutTradeNo(info.getOrderId());
			result.setTradeNo(info.getDealId());
		}else{
			result.setTradeStatus(KQResult.fail);
		}
		logger.info("块钱回调校验返回结果："+JSON.toJSONString(result));
		/*result.setVerifyResult(isVerify(info));
		if (result.isVerifyResult()) {
			switch (info.getPayResult()) {
			case "10":
				result.setTradeStatus(KQResult.success);
				result.setOutTradeNo(info.getOrderId());
				result.setTradeNo(info.getDealId());
				break;

			default:
				result.setTradeStatus(KQResult.fail);
				break;
			}
		}*/
		return result;
	}
	private static boolean isVerify(KQResultInfo info){
		String merchantSignMsgVal = "";
		merchantSignMsgVal = appendParam(merchantSignMsgVal,"merchantAcctId", info.getMerchantAcctId());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "version",info.getVersion());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "language",info.getLanguage());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "signType",info.getSignType());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "payType",info.getPayType());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "bankId",info.getBankId());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderId",info.getOrderId());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderTime",info.getOrderTime());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "orderAmount",info.getOrderAmount());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "bindCard",info.getBindCard());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "bindMobile",info.getBindMobile());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "dealId",info.getDealId());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "bankDealId",info.getBankDealId());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "dealTime",info.getDealTime());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "payAmount",info.getPayAmount());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "fee", info.getFee());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "ext1", info.getExt1());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "ext2", info.getExt2());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "payResult",info.getPayResult());
		merchantSignMsgVal = appendParam(merchantSignMsgVal, "errCode",info.getErrCode());
		Pkipair pki = new Pkipair();
		return pki.enCodeByCer(merchantSignMsgVal, info.getSignMsg());
	}
	private static String getString(KQPayInfo info) {
		String signMsgVal = "";
		signMsgVal = appendParam(signMsgVal, "inputCharset", info.getInputCharset());
		signMsgVal = appendParam(signMsgVal, "pageUrl", info.getPageUrl());
		signMsgVal = appendParam(signMsgVal, "bgUrl", info.getBgUrl());
		signMsgVal = appendParam(signMsgVal, "version", info.getVersion());
		signMsgVal = appendParam(signMsgVal, "language", info.getLanguage());
		signMsgVal = appendParam(signMsgVal, "signType", info.getSignType());
		signMsgVal = appendParam(signMsgVal, "merchantAcctId",info.getMerchantAcctId());
		signMsgVal = appendParam(signMsgVal, "payerName", info.getPayerName());
		signMsgVal = appendParam(signMsgVal, "payerContactType",info.getPayerContactType());
		signMsgVal = appendParam(signMsgVal, "payerContact", info.getPayerContact());
		signMsgVal = appendParam(signMsgVal, "payerIdType", info.getPayerIdType());
		signMsgVal = appendParam(signMsgVal, "payerId", info.getPayerId());
		signMsgVal = appendParam(signMsgVal, "orderId", info.getOrderId());
		signMsgVal = appendParam(signMsgVal, "orderAmount", info.getOrderAmount());
		signMsgVal = appendParam(signMsgVal, "orderTime", info.getOrderTime());
		signMsgVal = appendParam(signMsgVal, "productName", info.getProductName());
		signMsgVal = appendParam(signMsgVal, "productNum", info.getProductNum());
		signMsgVal = appendParam(signMsgVal, "productId", info.getProductId());
		signMsgVal = appendParam(signMsgVal, "productDesc", info.getProductDesc());
		signMsgVal = appendParam(signMsgVal, "ext1", info.getExt1());
		signMsgVal = appendParam(signMsgVal, "ext2", info.getExt2());
		signMsgVal = appendParam(signMsgVal, "payType", info.getPayType());
		signMsgVal = appendParam(signMsgVal, "bankId", info.getBankId());
		signMsgVal = appendParam(signMsgVal, "redoFlag", info.getRedoFlag());
		signMsgVal = appendParam(signMsgVal, "pid", info.getPid());
		return signMsgVal;
	}


	private static String getString2(KQPayInfo info) {
		String signMsgVal = "";
		signMsgVal = appendParam(signMsgVal, "inputCharset", info.getInputCharset());
		signMsgVal = appendParam(signMsgVal, "pageUrl", URLEncoder.encode(info.getPageUrl()));
		signMsgVal = appendParam(signMsgVal, "bgUrl", URLEncoder.encode(info.getBgUrl()));
		signMsgVal = appendParam(signMsgVal, "version", info.getVersion());
		signMsgVal = appendParam(signMsgVal, "language", info.getLanguage());
		signMsgVal = appendParam(signMsgVal, "signType", info.getSignType());
		signMsgVal = appendParam(signMsgVal, "signMsg", URLEncoder.encode(info.getSignMsg()));
		signMsgVal = appendParam(signMsgVal, "merchantAcctId",info.getMerchantAcctId());
		signMsgVal = appendParam(signMsgVal, "payerName", info.getPayerName());
		signMsgVal = appendParam(signMsgVal, "payerContactType",info.getPayerContactType());
		signMsgVal = appendParam(signMsgVal, "payerContact", info.getPayerContact());
		signMsgVal = appendParam(signMsgVal, "payerIdType", info.getPayerIdType());
		signMsgVal = appendParam(signMsgVal, "payerId", info.getPayerId());
		signMsgVal = appendParam(signMsgVal, "orderId", info.getOrderId());
		signMsgVal = appendParam(signMsgVal, "orderAmount", info.getOrderAmount());
		signMsgVal = appendParam(signMsgVal, "orderTime", info.getOrderTime());
		signMsgVal = appendParam(signMsgVal, "productName", info.getProductName());
		signMsgVal = appendParam(signMsgVal, "productNum", info.getProductNum());
		signMsgVal = appendParam(signMsgVal, "productId", info.getProductId());
		signMsgVal = appendParam(signMsgVal, "productDesc", info.getProductDesc());
		signMsgVal = appendParam(signMsgVal, "ext1", info.getExt1());
		signMsgVal = appendParam(signMsgVal, "ext2", info.getExt2());
		signMsgVal = appendParam(signMsgVal, "payType", info.getPayType());
		signMsgVal = appendParam(signMsgVal, "bankId", info.getBankId());
		signMsgVal = appendParam(signMsgVal, "redoFlag", info.getRedoFlag());
		signMsgVal = appendParam(signMsgVal, "pid", info.getPid());
		return signMsgVal;
	}

	private static Map<String, Object> getMap(KQPayInfo info) {
		Class infoClass = (Class) info.getClass();
		Map<String, Object>params=Maps.newHashMap(); 
		for (Field f : infoClass.getDeclaredFields()) {
			f.setAccessible(true); // 设置些属性是可以访问的
			try {
				Object val = f.get(info);
				params.put(f.getName(), val.toString());
			} catch (Exception e) {
				// TODO Auto-generated catch block
				logger.error("", e);
			} // 得到此属性的值
		}
		return params;
	}

	private static String appendParam(String returns, String paramId,
			String paramValue) {
		if (StringUtils.isNotBlank(returns)) {
			if (StringUtils.isNotBlank(paramValue)) {
				returns += "&" + paramId + "=" + paramValue;
			}

		} else {
			if (StringUtils.isNotBlank(paramValue) ) {
				returns = paramId + "=" + paramValue;
			}
		}
		return returns;
	}

}
